package com.linkhub.oms.data.sync.api.shopify.domain.response;

import cn.hutool.core.collection.CollUtil;
import com.alibaba.fastjson.annotation.JSONField;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.google.common.collect.Lists;
import com.linkhub.oms.common.util.OffSetDateTimeUtil;
import com.linkhub.oms.common.util.QtStreamUtil;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;

import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.Collection;
import java.util.Comparator;
import java.util.List;
import java.util.function.Function;

/**
 * @Description: ShopOrderResponse
 * @Author: echo
 * @Date: 2024/3/29 18:31
 * @Version: 1.0
 */
@Data
@EqualsAndHashCode(callSuper = true)
@NoArgsConstructor
public class ShopOrderResponse extends BaseResponse implements Serializable {

    public static final String FIELDS = "id,current_total_price," +
            "currency," +
            "cancel_reason," +
            "cancelled_at," +
            "created_at," +
            "email," +
            "financial_status," +
            "fulfillment_status," +
            "note," +
            "order_number," +
            "processed_at," +
            "updated_at," +
            "fulfillments," +
            "line_items," +
            "shipping_address," +
            "shipping_lines";

    public static final String IDS_FIELDS = "id,updated_at,order_number";

    /**
     * orders
     */
    @JSONField(name = "orders")
    private List<Orders> orders;


    @Override
    @JSONField(serialize = false, deserialize = false)
    public boolean success() {
        return CollUtil.isNotEmpty(orders);
    }

    public void addAll(List<ShopOrderResponse.Orders> orders) {

        QtStreamUtil.peek(orders,
                order -> order.setUpdatedTime(OffSetDateTimeUtil.convertISO8601ToUTCDateTime(order.getUpdatedAt())));

        CollUtil.addAll(this.getOrders(), orders);
        Collection<Orders> distinct = QtStreamUtil.toMap(this.getOrders(),
                Orders::getOrderNumber, Function.identity())
                .values();

        this.setOrders(Lists.newArrayList(distinct));

        this.getOrders().sort(Comparator.comparing(ShopOrderResponse.Orders::getUpdatedTime));

    }

    @Override
    @JSONField(serialize = false, deserialize = false)
    public int count() {
        return CollUtil.size(this.getOrders());
    }

    @Override
    public String maxUpdateTime() {
        List<Orders> orders = this.getOrders();
        return orders.get(orders.size() - 1).getUpdatedAt();
    }

    public static ShopOrderResponse emptyResponse() {
        ShopOrderResponse res =  new ShopOrderResponse();
        res.setOrders(Lists.newArrayList());
        return res;
    }




    /**
     * Orders
     */
    @NoArgsConstructor
    @Data
    public static class Orders {

        @JSONField(name = "id")
        private Long id;


        /**
         * currentTotalPrice
         */
        @JSONField(name = "current_total_price")
        private String currentTotalPrice;
        /**
         * cancelReason
         */
        @JSONField(name = "cancel_reason")
        private String cancelReason;
        /**
         * cancelledAt
         */
        @JSONField(name = "cancelled_at")
        private String cancelledAt;
        /**
         * createdAt
         */
        @JSONField(name = "created_at")
        private String createdAt;
        /**
         * email
         */
        @JSONField(name = "email")
        private String email;
        /**
         * financialStatus
         */
        @JSONField(name = "financial_status")
        private String financialStatus;
        /**
         * fulfillmentStatus
         */
        @JSONField(name = "fulfillment_status")
        private String fulfillmentStatus;
        /**
         * note
         */
        @JSONField(name = "note")
        private String note;
        /**
         * orderNumber
         */
        @JSONField(name = "order_number")
        private Integer orderNumber;
        /**
         * processedAt
         */
        @JSONField(name = "processed_at")
        private String processedAt;
        /**
         * updatedAt
         */
        @JSONField(name = "updated_at")
        private String updatedAt;

        /**
         * 通过 updatedAt 转换
         */
        @JsonIgnore
        @JSONField(serialize = false, deserialize = false)
        private LocalDateTime updatedTime;

        /**
         * fulfillments
         */
        @JSONField(name = "fulfillments")
        private List<Fulfillments> fulfillments;
        /**
         * lineItems
         */
        @JSONField(name = "line_items")
        private List<LineItems> lineItems;
        /**
         * shippingAddress
         */
        @JSONField(name = "shipping_address")
        private ShippingAddress shippingAddress;
        /**
         * shippingLines
         */
        @JSONField(name = "shipping_lines")
        private List<ShippingLines> shippingLines;

        /**
         * currency
         */
        @JSONField(name = "currency")
        private String currency;

        /**
         * ShippingAddress
         */
        @NoArgsConstructor
        @Data
        public static class ShippingAddress {
            /**
             * firstName
             */
            @JSONField(name = "first_name")
            private String firstName;
            /**
             * address1
             */
            @JSONField(name = "address1")
            private String address1;
            /**
             * phone
             */
            @JSONField(name = "phone")
            private String phone;
            /**
             * city
             */
            @JSONField(name = "city")
            private String city;
            /**
             * zip
             */
            @JSONField(name = "zip")
            private String zip;
            /**
             * province
             */
            @JSONField(name = "province")
            private String province;
            /**
             * country
             */
            @JSONField(name = "country")
            private String country;
            /**
             * lastName
             */
            @JSONField(name = "last_name")
            private String lastName;
            /**
             * address2
             */
            @JSONField(name = "address2")
            private String address2;
            /**
             * company
             */
            @JSONField(name = "company")
            private String company;
            /**
             * latitude
             */
            @JSONField(name = "latitude")
            private String latitude;
            /**
             * longitude
             */
            @JSONField(name = "longitude")
            private String longitude;
            /**
             * name
             */
            @JSONField(name = "name")
            private String name;
            /**
             * countryCode
             */
            @JSONField(name = "country_code")
            private String countryCode;
            /**
             * provinceCode
             */
            @JSONField(name = "province_code")
            private String provinceCode;
        }

        /**
         * Fulfillments
         */
        @NoArgsConstructor
        @Data
        public static class Fulfillments {
            /**
             * trackingCompany
             */
            @JSONField(name = "tracking_company")
            private String trackingCompany;
            /**
             * trackingNumber
             */
            @JSONField(name = "tracking_numbers")
            private List<String> trackingNumbers;
            /**
             * trackingUrls
             */
            @JSONField(name = "tracking_urls")
            private List<String> trackingUrls;
        }

        /**
         * LineItems
         */
        @NoArgsConstructor
        @Data
        public static class LineItems {
            /**
             * currentQuantity
             */
            @JSONField(name = "current_quantity")
            private Integer currentQuantity;
            /**
             * fulfillableQuantity
             */
            @JSONField(name = "fulfillable_quantity")
            private Integer fulfillableQuantity;
            /**
             * name
             */
            @JSONField(name = "name")
            private String name;
            /**
             * price
             */
            @JSONField(name = "price")
            private String price;
            /**
             * price_set
             */
            @JSONField(name = "price_set")
            private PriceSet priceSet;
            /**
             * productId
             */
            @JSONField(name = "product_id")
            private Long productId;
            /**
             * quantity
             */
            @JSONField(name = "quantity")
            private Integer quantity;
            /**
             * sku
             */
            @JSONField(name = "sku")
            private String sku;
            /**
             * variantId
             */
            @JSONField(name = "variant_id")
            private Long variantId;


        }

        /**
         * PriceSet
         */
        @NoArgsConstructor
        @Data
        public static class PriceSet {
            /**
             * shop_money
             */
            @JSONField(name = "shop_money")
            private ShopMoney shopMoney;
        }

        /**
         * ShopMoney
         */
        @NoArgsConstructor
        @Data
        public static class ShopMoney {
            /**
             * amount
             */
            @JSONField(name = "amount")
            private String amount;
            /**
             * currency_code
             */
            @JSONField(name = "currency_code")
            private String currencyCode;
        }

        /**
         * ShippingLines
         */
        @NoArgsConstructor
        @Data
        public static class ShippingLines {
            /**
             * title
             */
            @JSONField(name = "title")
            private String title;
        }
    }
}
